<template>
    <div class="halo-tree" :class="{'halo-tree-padding': isPaddingLeft}">
        <tree-node
          :isLazy="isLazy"
          :treeData='store.root'
          :options="treeNodeOptions"
          @handlecheckedChange="handlecheckedChange">
        </tree-node>
    </div>
</template>
<script>
    import TreeNode from './tree-node.vue'
    import TreeStore from './tree-store'

    const DEFAULTICONCLASS = {
      open: 'icon-triangle-down',
      close: 'icon-triangle-right',
      add: 'icon-add'
    }
    export default {
      name: 'zz-tree',
      props: {
        treeData: [Array],
        isPaddingLeft: {
          type: Boolean,
          default: false
        },
        isLazy: {
          type: Boolean,
          default: false
        },
        options: {
          type: Object,
          default () {
            return {
              halfCheckedStatus: true
            }
          }
        }
      },
      data () {
        return {
          treeNodeOptions: {},
          store: {
            root: [],
            last: null
          }
        }
      },
      created () {
        this.isTree = true
        this.dealTreeData()
        this.checkOptions() // check options
        this.treeNodeOptions = Object.assign({}, {
          rootName: '根节点',
          labelKey: 'label',      // 默认的标题字段
          iconClass: DEFAULTICONCLASS,
          lazy: false,            // 异步加载
          load: () => {},
          leafIcon () { return '' } // not required
        },
          this.options)
      },

      watch: {
        treeData: {
          handler: function (data, oldData) {
            this.dealTreeData()
          },
          deep: true
        }
      },
      methods: {
        /**
         * generate key 0-1-2-3
         * this is very important function for now module
         * @param treeData
         * @param parentKey
         * @returns {Array}
         */
        generateKey (treeData = [], parentKey) {
          treeData = treeData.map((item, i) => {
            item.key = parentKey + '-' + i.toString()
            if (item.hasOwnProperty('children') && item.children.length > 0) {
              this.generateKey(item.children, item.key)
            }
            return item
          })
          return treeData
        },
        handlecheckedChange (node) {
          if (this.options.halfCheckedStatus) {
            this.store.changeCheckHalfStatus(node, this.options.noParentChecked)
          } else {
            this.store.changeCheckStatus(node, this.options.noParentChecked)
          }
          this.$emit('handlecheckedChange', node)
        },
        getParentNode (node) {
          const key = node.key.substring(0, node.key.length - 2)
          let items = [...this.store.datas.values()]
          for (let item of items) {
            if (key === item.key) {
              return item
            }
          }
        },
        getSelectedNodes () {
          const allnodes = this.store.datas
          let selectedNodes = []
          for (let [, node] of allnodes) {
            if (node.checked) {
              selectedNodes.push(node)
            }
          }
          return selectedNodes
        },
        getSelectedNodeIds () {
          const allnodes = this.store.datas
          let selectedNodeIds = []
          for (let [, node] of allnodes) {
            if (node.checked && !node.nodeSelectNotAll) {
              selectedNodeIds.push(node.id)
            }
          }
          return selectedNodeIds
        },
        /**
         * 初始化时检查 参数
         */
        checkOptions () {
          if ('lazy' in this.options) {
            if (typeof this.options.load !== 'function') {
              console.error('load must be Function')
            }
          }
          if ('leafIcon' in this.options) {
            if (typeof this.options.leafIcon !== 'function') {
              console.error('leafIcon must be Function')
            }
          }
        },
        /**
         * del tree data
         * when created, update, dynamic add node
         */
        dealTreeData () {
          this.store = new TreeStore({
            root: (this.generateKey(this.treeData, '0') || []).slice(0)
          })
        }
      },
      components: {TreeNode}
    }

</script>
<style lang="scss" scoped>
  .halo-tree{
    width: 100%;
    .icon {
      display: inline-block;
      margin-right: 10px;
      vertical-align: middle;
    }
  }
</style>

